/*
 ============================================================================
 Name        : LibreriaLogueo.c
 Author      : SOogle
 Version     : 1.0
 Copyright   : All rights reserved
 Description : FUSELAGE - FUSE FAT32 FILE SYSTEM
 ============================================================================
 */

/*
 * Copyright (c) 2011, C-Talks and/or its owners. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact C-Talks owners, Matias Dumrauf or Facundo Viale
 * or visit https://sites.google.com/site/utnfrbactalks/ if you need additional
 * information or have any questions.
 */

/*
 *	@FILE: 	log.c
 *	@AUTOR: Facundo Viale
 *	@VERSION:	2.0	(5/08/2011)
 *					- Improvements
 *				1.5	(29/08/2009)
 *					- Full Revision
 */

#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <sys/timeb.h>
#include <pthread.h>
#include <semaphore.h>

#include "../../headers/GlobalHeader.h"

extern int32_t sizeCola, sizeColaActiva, algoritmoUtilizado;
extern t_Cola *colaPedidos, *colaActiva;
extern PPD_CHS posicionActualCabezal, proximoSectorPlanifico;
extern struct_config configuracion;
extern t_log *logger;

/*
 ============================================================================
 FUNCIONES PRIVADAS
 ============================================================================
 */

/*
 * Private Functions
 */
inline static int log_vwrite(t_log *log, const char *thread_name, e_message_level level, const char* format, va_list args_list);
static char *log_error_as_string(e_message_level type);

/*
 * Public Functions
 */

/*
 * @NAME: log_create
 * @DESC: Crea un log
 */
t_log *log_create(const char *program_name, const char* file_name, unsigned char log_levels, e_console_mode console_mode) {
	pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
	t_log* log = malloc(sizeof(t_log));

	log->file = NULL;

	if (file_name != NULL && (log->file = fopen(file_name, "a")) == NULL) {
		free(log);
		return NULL;
	}

	log->mutex = mutex;

	log->console_mode = console_mode;

	if( program_name != NULL ){
		log->program_name = program_name;
	} else {
		log->program_name = "";
	}

	log->program_pid = getpid();

	log->log_levels = log_levels;

	return log;
}

/*
 * @NAME: log_info
 * @DESC: Escribe en el log un mensaje con el nivel info
 */
int log_info(t_log *log, const char *thread_name, const char* format, ... ) {
	va_list args_list;
	va_start(args_list, format);
	return log_vwrite(log, thread_name, INFO, format, args_list);
}

/*
 * @NAME: log_warning
 * @DESC: Escribe en el log un mensaje con el nivel warning
 */
int log_warning(t_log *log, const char *thread_name, const char* format, ... ) {
	va_list args_list;
	va_start(args_list, format);
	return log_vwrite(log, thread_name, WARNING, format, args_list);
}

/*
 * @NAME: log_error
 * @DESC: Escribe en el log un mensaje con el nivel error
 */
int log_error(t_log *log, const char *thread_name, const char* format, ... ) {
	va_list args_list;
	va_start(args_list, format);
	return log_vwrite(log, thread_name, ERROR, format, args_list);
}

/*
 * @NAME: log_debug
 * @DESC: Escribe en el log un mensaje con el nivel debug
 */
int log_debug(t_log *log, const char *thread_name, const char* format, ... ) {
	va_list args_list;
	va_start(args_list, format);
	return log_vwrite(log, thread_name, DEBUG, format, args_list);
}

/*
 * @NAME: log_vwrite
 * @DESC: Genera el log!
 */
inline static int log_vwrite(t_log *log, const char *thread_name, e_message_level level, const char* format, va_list args_list) {
	time_t log_time;
	struct tm *log_tm;
	struct timeb tmili;
	char str_time[128];
	unsigned int thread_id = pthread_self();
	char *str_type = log_error_as_string(level);
	char logbuff[LOG_MAX_MESSAGE_LENGTH + 100];char
	msgbuff[LOG_MAX_MESSAGE_LENGTH];

	if (!log_has_level(log, level)) {
		return 1;
	}

	pthread_mutex_lock(&log->mutex);

	vsprintf(msgbuff, format, args_list);

	if ((log_time = time(NULL)) == -1) {
		perror("[[CRITICAL]] :: Error getting date!");
		return 0;
	}

	log_tm = localtime(&log_time);
	strftime(str_time, 127, "%H:%M:%S", log_tm);

	if (ftime(&tmili)) {
		perror("[[CRITICAL]] :: Error getting time!");
		return 0;
	}

	sprintf(logbuff, "%s:%hu %s/%d %s/%u %s: %s\n", str_time, tmili.millitm, log->program_name, log->program_pid, thread_name, thread_id, str_type, msgbuff);

	if ( log->file != NULL ) {
		fprintf(log->file, "%s", logbuff);
		fflush(log->file);
	}

	if ( log->console_mode == M_CONSOLE_ENABLE ) {
		printf("%s", logbuff);
		fflush(stdout);
	}
	pthread_mutex_unlock(&log->mutex);

	return 1;
}

/*
 * @NAME: log_errorTypeAsString
 * @DESC: Convierte un tipo numerico de error a su version en string
 */
static char *log_error_as_string(e_message_level type) {
	if (type == ERROR)
		return "ERROR";
	if (type == WARNING)
		return "WARNING";
	if (type == INFO)
		return "INFO";
	if (type == DEBUG)
		return "DEBUG";
	return "UNKNOW_MSG_TYPE";
}

/*
 * @NAME: log_destroy
 * @DESC: Destruye el puntero al log y cierra el archivo
 */
void log_destroy(t_log *log) {
	if (log != NULL) {
		fclose(log->file);
		pthread_mutex_destroy(&log->mutex);
		free(log);
	}
}

/*
 ============================================================================
 FUNCIONES PROPIAS
 ============================================================================
 */

int32_t *armarColaLogueoSSTF()
{

	int32_t *resultado;
	int32_t current = 0;
	int32_t tamanio = 0;
	int32_t i = 0, j  = 0;
	t_nodoCola *aux;

	aux = colaPedidos->frente;

	sem_getvalue(&colaPedidos->cantidadPedidos, &tamanio);

	if(tamanio <= 6)
	{
		resultado = malloc(sizeof(int32_t)*tamanio);

		while (aux != NULL && i <= tamanio)
		{
			int32_t valorAgrego = aux->pedido.direccionSector;
			memcpy(resultado + current, &valorAgrego, sizeof(int32_t));
			current++;
			i++;
			aux = aux->siguiente;
		}
	}
	else
	{
		resultado = malloc(sizeof(int32_t)*6);

		i = 0;

		while(aux != NULL)
		{
			if (i < 3)
			{
				while(i < 3 && aux != NULL)
				{
					int32_t valorAgrego = aux->pedido.direccionSector;
					memcpy(resultado + current, &valorAgrego, sizeof(int32_t));
					current++;
					aux = aux->siguiente;
					i++;
				}
			}
			else
			{
				if(i >= tamanio - 3)
				{
					for (j = i; j<sizeCola; j++)
					{
						int32_t valorAgrego = aux->pedido.direccionSector;
						memcpy(resultado + current, &valorAgrego, sizeof(int32_t));
						current++;
						aux = aux->siguiente;
					}
				}
				else
				{
					aux = aux->siguiente;
					i++;
				}
			}
		}
	}
	return resultado;
}

int32_t *armarColaLogueoNSTEP()
{
	int32_t *resultado;
	int32_t tamanioPasiva, tamanioActiva;

	t_nodoCola *aux;

	sem_getvalue(&colaPedidos->cantidadPedidos, &tamanioPasiva);

	sem_getvalue(&colaActiva->cantidadPedidos, &sizeColaActiva);

	tamanioActiva = sizeColaActiva;

	if(tamanioPasiva + tamanioActiva >= 6)
	{
		resultado = (int32_t *) malloc(sizeof(int32_t)*6);
	}
	else
	{
		resultado = (int32_t *) malloc(sizeof(int32_t)*(tamanioPasiva + tamanioActiva));
	}

	aux = colaActiva->frente;
	int32_t current = 0;
	int32_t i = 0;
	int32_t j = 0;

	//TIENEN PRIORIDAD LOS PEDIDOS DE LA COLA ACTIVA
	while(aux != NULL)
	{
		int32_t valorAgrego = aux->pedido.direccionSector;
		memcpy(resultado + current, &valorAgrego, sizeof(int32_t));
		current++;
		i++;
		aux = aux->siguiente;
	}

	if (i < 6)
	{
		aux = colaPedidos->frente;

		//DIFERENCIA ES LA CANTIDAD DE PEDIDOS QUE ME FALTAN AGREGAR A LA COLA DE LOGUEO, YA QUE NO SE LA CANTIDAD EXACTA DE LA ACTIVA
		int32_t diferencia = 6 - i;

		//EN ESTE IF VOY A ENTRAR CUANDO I APUNTE A LOS ULTIMOS NODOS QUE ES LA CANTIDAD QUE ME FALTA COMPLETAR PARA LLEGAR A 6
		if(i >= tamanioPasiva - diferencia)
		{
			for (j = i; j<tamanioPasiva; j++)
			{
				int32_t valorAgrego = aux->pedido.direccionSector;
				memcpy(resultado + current, &valorAgrego, sizeof(int32_t));
				current++;
				aux = aux->siguiente;
			}
		}
		else
		{
			aux = aux->siguiente;
			i++;
		}
	}
	return resultado;
}

void logueoInformacionProceso(t_pedido pedidoPorProcesar, int32_t *colaLogueo)
{
	PPD_CHS sectorPedido1, sectorPedido2, sectorPedido3, sectorPedido4, sectorPedido5, sectorPedido6;
	int32_t *sectores;
	char *sectoresRecorridos;

	/*switch (algoritmoUtilizado)
	{
		case CON_INANICION :*/
			switch(sizeCola)
			{
				case 1 :
					sectorPedido1 = ppd_LBAToCHS(colaLogueo[0]);
					log_info(logger, "PROCESO PEDIDO ELEGIDO", "Cola de Pedidos: [ %i:%i ] Tamaño: %i\n", sectorPedido1.cylinder, sectorPedido1.sector, sizeCola);
					log_info(logger, "PROCESO PEDIDO ELEGIDO", "Posicion Actual: %i:%i\n", posicionActualCabezal.cylinder, posicionActualCabezal.sector);
					sectorPedido1 = ppd_LBAToCHS(pedidoPorProcesar.direccionSector);
					log_info(logger, "PROCESO PEDIDO ELEGIDO", "Sector Solicitado: %i:%i\n", sectorPedido1.cylinder, sectorPedido1.sector);

					//ESTA FUNCION ME DEVUELVE UN ARRAY CON LOS SECTORES QUE RECORRO PARA LLEGAR AL SECTOR QUE SE VA A PROCESAR
					sectores = SectoresRecorro(posicionActualCabezal, sectorPedido1);

					//ESTA FUNCION CONVIERTE EL ARRAY DE INTS A CHAR* PARA SER LOGUEADO
					sectoresRecorridos = armarSectoresRecorridosLogueo(sectores, diferenciaEntreSectores(posicionActualCabezal, sectorPedido1));
					log_info(logger, "PROCESO PEDIDO ELEGIDO", "Sectores Recorridos: %s\n", sectoresRecorridos);
					log_info(logger, "PROCESO PEDIDO ELEGIDO", "Tiempo consumido: %f ms\n", tiempoEntreSectores(posicionActualCabezal, sectorPedido1));
					imprimirProximoSectorLogueo();

					free(sectores);
					free(sectoresRecorridos);

					break;

				case 2 :
					sectorPedido1 = ppd_LBAToCHS(colaLogueo[0]);
					sectorPedido2 = ppd_LBAToCHS(colaLogueo[1]);
					log_info(logger, "PROCESO PEDIDO ELEGIDO", "Cola de Pedidos: [ %i:%i, %i:%i ] Tamaño: %i\n", sectorPedido1.cylinder, sectorPedido1.sector, sectorPedido2.cylinder, sectorPedido2.sector, sizeCola);
					log_info(logger, "PROCESO PEDIDO ELEGIDO", "Posicion Actual: %i:%i\n", posicionActualCabezal.cylinder, posicionActualCabezal.sector);
					sectorPedido1 = ppd_LBAToCHS(pedidoPorProcesar.direccionSector);
					log_info(logger, "PROCESO PEDIDO ELEGIDO", "Sector Solicitado: %i:%i\n", sectorPedido1.cylinder, sectorPedido1.sector);
					sectores = SectoresRecorro(posicionActualCabezal, sectorPedido1);
					sectoresRecorridos = armarSectoresRecorridosLogueo(sectores, diferenciaEntreSectores(posicionActualCabezal, sectorPedido1));
					log_info(logger, "PROCESO PEDIDO ELEGIDO", "Sectores Recorridos: %s\n", sectoresRecorridos);
					log_info(logger, "PROCESO PEDIDO ELEGIDO", "Tiempo consumido: %f ms\n", tiempoEntreSectores(posicionActualCabezal, sectorPedido1));
					imprimirProximoSectorLogueo();

					free(sectores);
					free(sectoresRecorridos);
					break;
				case 3:
					sectorPedido1 = ppd_LBAToCHS(colaLogueo[0]);
					sectorPedido2 = ppd_LBAToCHS(colaLogueo[1]);
					sectorPedido3 = ppd_LBAToCHS(colaLogueo[2]);
					log_info(logger, "PROCESO PEDIDO ELEGIDO", "Cola de Pedidos: [ %i:%i, %i:%i, %i:%i ] Tamaño: %i\n", sectorPedido1.cylinder, sectorPedido1.sector, sectorPedido2.cylinder, sectorPedido2.sector, sectorPedido3.cylinder, sectorPedido3.sector, sizeCola);
					log_info(logger, "PROCESO PEDIDO ELEGIDO", "Posicion Actual: %i:%i\n", posicionActualCabezal.cylinder, posicionActualCabezal.sector);
					sectorPedido1 = ppd_LBAToCHS(pedidoPorProcesar.direccionSector);
					log_info(logger, "PROCESO PEDIDO ELEGIDO", "Sector Solicitado: %i:%i\n", sectorPedido1.cylinder, sectorPedido1.sector);
					sectores = SectoresRecorro(posicionActualCabezal, sectorPedido1);
					sectoresRecorridos = armarSectoresRecorridosLogueo(sectores, diferenciaEntreSectores(posicionActualCabezal, sectorPedido1));
					log_info(logger, "PROCESO PEDIDO ELEGIDO", "Sectores Recorridos: %s\n", sectoresRecorridos);
					log_info(logger, "PROCESO PEDIDO ELEGIDO", "Tiempo consumido: %f ms\n", tiempoEntreSectores(posicionActualCabezal, sectorPedido1));
					imprimirProximoSectorLogueo();
					free(sectores);
					free(sectoresRecorridos);
					break;
				case 4:
					sectorPedido1 = ppd_LBAToCHS(colaLogueo[0]);
					sectorPedido2 = ppd_LBAToCHS(colaLogueo[1]);
					sectorPedido3 = ppd_LBAToCHS(colaLogueo[2]);
					sectorPedido4 = ppd_LBAToCHS(colaLogueo[3]);
					log_info(logger, "PROCESO PEDIDO ELEGIDO", "Cola de Pedidos: [ %i:%i, %i:%i, %i:%i, %i:%i ] Tamaño: %i\n", sectorPedido1.cylinder, sectorPedido1.sector, sectorPedido2.cylinder, sectorPedido2.sector, sectorPedido3.cylinder, sectorPedido3.sector, sectorPedido4.cylinder, sectorPedido4.sector, sizeCola);
					log_info(logger, "PROCESO PEDIDO ELEGIDO", "Posicion Actual: %i:%i\n", posicionActualCabezal.cylinder, posicionActualCabezal.sector);
					sectorPedido1 = ppd_LBAToCHS(pedidoPorProcesar.direccionSector);
					log_info(logger, "PROCESO PEDIDO ELEGIDO", "Sector Solicitado: %i:%i\n", sectorPedido1.cylinder, sectorPedido1.sector);
					sectores = SectoresRecorro(posicionActualCabezal, sectorPedido1);
					sectoresRecorridos = armarSectoresRecorridosLogueo(sectores, diferenciaEntreSectores(posicionActualCabezal, sectorPedido1));
					log_info(logger, "PROCESO PEDIDO ELEGIDO", "Sectores Recorridos: %s\n", sectoresRecorridos);
					log_info(logger, "PROCESO PEDIDO ELEGIDO", "Tiempo consumido: %f ms\n", tiempoEntreSectores(posicionActualCabezal, sectorPedido1));
					imprimirProximoSectorLogueo();
					free(sectores);
					free(sectoresRecorridos);
					break;
				case 5:
					sectorPedido1 = ppd_LBAToCHS(colaLogueo[0]);
					sectorPedido2 = ppd_LBAToCHS(colaLogueo[1]);
					sectorPedido3 = ppd_LBAToCHS(colaLogueo[2]);
					sectorPedido4 = ppd_LBAToCHS(colaLogueo[3]);
					sectorPedido5 = ppd_LBAToCHS(colaLogueo[4]);
					log_info(logger, "PROCESO PEDIDO ELEGIDO", "Cola de Pedidos: [ %i:%i, %i:%i, %i:%i, %i:%i, %i:%i ] Tamaño: %i\n", sectorPedido1.cylinder, sectorPedido1.sector, sectorPedido2.cylinder, sectorPedido2.sector, sectorPedido3.cylinder, sectorPedido3.sector, sectorPedido4.cylinder, sectorPedido4.sector,sectorPedido5.cylinder, sectorPedido5.sector, sizeCola);
					log_info(logger, "PROCESO PEDIDO ELEGIDO", "Posicion Actual: %i:%i\n", posicionActualCabezal.cylinder, posicionActualCabezal.sector);
					sectorPedido1 = ppd_LBAToCHS(pedidoPorProcesar.direccionSector);
					log_info(logger, "PROCESO PEDIDO ELEGIDO", "Sector Solicitado: %i:%i\n", sectorPedido1.cylinder, sectorPedido1.sector);
					sectores = SectoresRecorro(posicionActualCabezal, sectorPedido1);
					sectoresRecorridos = armarSectoresRecorridosLogueo(sectores, diferenciaEntreSectores(posicionActualCabezal, sectorPedido1));
					log_info(logger, "PROCESO PEDIDO ELEGIDO", "Sectores Recorridos: %s\n", sectoresRecorridos);
					log_info(logger, "PROCESO PEDIDO ELEGIDO", "Tiempo consumido: %f ms\n", tiempoEntreSectores(posicionActualCabezal, sectorPedido1));
					imprimirProximoSectorLogueo();
					free(sectores);
					free(sectoresRecorridos);
					break;
				case 6:
					sectorPedido1 = ppd_LBAToCHS(colaLogueo[0]);
					sectorPedido2 = ppd_LBAToCHS(colaLogueo[1]);
					sectorPedido3 = ppd_LBAToCHS(colaLogueo[2]);
					sectorPedido4 = ppd_LBAToCHS(colaLogueo[3]);
					sectorPedido5 = ppd_LBAToCHS(colaLogueo[4]);
					sectorPedido6 = ppd_LBAToCHS(colaLogueo[5]);
					log_info(logger, "PROCESO PEDIDO ELEGIDO", "Cola de Pedidos: [ %i:%i, %i:%i, %i:%i, %i:%i, %i:%i, %i:%i ] Tamaño: %i\n", sectorPedido1.cylinder, sectorPedido1.sector, sectorPedido2.cylinder, sectorPedido2.sector, sectorPedido3.cylinder, sectorPedido3.sector, sectorPedido4.cylinder, sectorPedido4.sector,sectorPedido5.cylinder, sectorPedido5.sector, sectorPedido6.cylinder, sectorPedido6.sector, sizeCola);
					log_info(logger, "PROCESO PEDIDO ELEGIDO", "Posicion Actual: %i:%i\n", posicionActualCabezal.cylinder, posicionActualCabezal.sector);
					sectorPedido1 = ppd_LBAToCHS(pedidoPorProcesar.direccionSector);
					log_info(logger, "PROCESO PEDIDO ELEGIDO", "Sector Solicitado: %i:%i\n", sectorPedido1.cylinder, sectorPedido1.sector);
					sectores = SectoresRecorro(posicionActualCabezal, sectorPedido1);
					sectoresRecorridos = armarSectoresRecorridosLogueo(sectores, diferenciaEntreSectores(posicionActualCabezal, sectorPedido1));
					log_info(logger, "PROCESO PEDIDO ELEGIDO", "Sectores Recorridos: %s\n", sectoresRecorridos);
					log_info(logger, "PROCESO PEDIDO ELEGIDO", "Tiempo consumido: %f ms\n", tiempoEntreSectores(posicionActualCabezal, sectorPedido1));
					imprimirProximoSectorLogueo();
					free(sectores);
					free(sectoresRecorridos);
					break;
				default :
					sectorPedido1 = ppd_LBAToCHS(colaLogueo[0]);
					sectorPedido2 = ppd_LBAToCHS(colaLogueo[1]);
					sectorPedido3 = ppd_LBAToCHS(colaLogueo[2]);
					sectorPedido4 = ppd_LBAToCHS(colaLogueo[3]);
					sectorPedido5 = ppd_LBAToCHS(colaLogueo[4]);
					sectorPedido6 = ppd_LBAToCHS(colaLogueo[5]);
					log_info(logger, "PROCESO PEDIDO ELEGIDO", "Cola de Pedidos: [ %i:%i, %i:%i, %i:%i ...  %i:%i, %i:%i, %i:%i ] Tamaño: %i\n", sectorPedido1.cylinder, sectorPedido1.sector, sectorPedido2.cylinder, sectorPedido2.sector, sectorPedido3.cylinder, sectorPedido3.sector, sectorPedido4.cylinder, sectorPedido4.sector,sectorPedido5.cylinder, sectorPedido5.sector, sectorPedido6.cylinder, sectorPedido6.sector, sizeCola);
					log_info(logger, "PROCESO PEDIDO ELEGIDO", "Posicion Actual: %i:%i\n", posicionActualCabezal.cylinder, posicionActualCabezal.sector);
					sectorPedido1 = ppd_LBAToCHS(pedidoPorProcesar.direccionSector);
					log_info(logger, "PROCESO PEDIDO ELEGIDO", "Sector Solicitado: %i:%i\n", sectorPedido1.cylinder, sectorPedido1.sector);
					sectores = SectoresRecorro(posicionActualCabezal, sectorPedido1);
					sectoresRecorridos = armarSectoresRecorridosLogueo(sectores, diferenciaEntreSectores(posicionActualCabezal, sectorPedido1));
					log_info(logger, "PROCESO PEDIDO ELEGIDO", "Sectores Recorridos: %s\n", sectoresRecorridos);
					log_info(logger, "PROCESO PEDIDO ELEGIDO", "Tiempo consumido: %f ms\n", tiempoEntreSectores(posicionActualCabezal, sectorPedido1));
					imprimirProximoSectorLogueo();
					free(sectores);
					free(sectoresRecorridos);
					break;
			}
		/*	break;

				case SIN_INANICION :
					switch(sizeCola+sizeColaActiva)
					{
						case 1 :
							sectorPedido1 = ppd_LBAToCHS(colaLogueo[0]);
							log_info(logger, "PROCESO PEDIDO ELEGIDO", "Cola de Pedidos: [ %i:%i ] Tamaño: %i\n", sectorPedido1.cylinder, sectorPedido1.sector, sizeCola+sizeColaActiva);
							log_info(logger, "PROCESO PEDIDO ELEGIDO", "Posicion Actual: %i:%i\n", posicionActualCabezal.cylinder, posicionActualCabezal.sector);
							sectorPedido1 = ppd_LBAToCHS(pedidoPorProcesar.direccionSector);
							log_info(logger, "PROCESO PEDIDO ELEGIDO", "Sector Solicitado: %i:%i\n", sectorPedido1.cylinder, sectorPedido1.sector);

							//ESTA FUNCION ME DEVUELVE UN ARRAY CON LOS SECTORES QUE RECORRO PARA LLEGAR AL SECTOR QUE SE VA A PROCESAR
							sectores = SectoresRecorro(posicionActualCabezal, sectorPedido1);

							//ESTA FUNCION CONVIERTE EL ARRAY DE INTS A CHAR* PARA SER LOGUEADO
							sectoresRecorridos = armarSectoresRecorridosLogueo(sectores, diferenciaEntreSectores(posicionActualCabezal, sectorPedido1));
							log_info(logger, "PROCESO PEDIDO ELEGIDO", "Sectores Recorridos: %s\n", sectoresRecorridos);
							log_info(logger, "PROCESO PEDIDO ELEGIDO", "Tiempo consumido: %f ms\n", tiempoEntreSectores(posicionActualCabezal, sectorPedido1));
							imprimirProximoSectorLogueo();
							free(sectores);
							free(sectoresRecorridos);
							break;

						case 2 :
							sectorPedido1 = ppd_LBAToCHS(colaLogueo[0]);
							sectorPedido2 = ppd_LBAToCHS(colaLogueo[1]);
							log_info(logger, "PROCESO PEDIDO ELEGIDO", "Cola de Pedidos: [ %i:%i, %i:%i ] Tamaño: %i\n", sectorPedido1.cylinder, sectorPedido1.sector, sectorPedido2.cylinder, sectorPedido2.sector, sizeCola+sizeColaActiva);
							log_info(logger, "PROCESO PEDIDO ELEGIDO", "Posicion Actual: %i:%i\n", posicionActualCabezal.cylinder, posicionActualCabezal.sector);
							sectorPedido1 = ppd_LBAToCHS(pedidoPorProcesar.direccionSector);
							log_info(logger, "PROCESO PEDIDO ELEGIDO", "Sector Solicitado: %i:%i\n", sectorPedido1.cylinder, sectorPedido1.sector);
							sectores = SectoresRecorro(posicionActualCabezal, sectorPedido1);
							sectoresRecorridos = armarSectoresRecorridosLogueo(sectores, diferenciaEntreSectores(posicionActualCabezal, sectorPedido1));
							log_info(logger, "PROCESO PEDIDO ELEGIDO", "Sectores Recorridos: %s\n", sectoresRecorridos);
							log_info(logger, "PROCESO PEDIDO ELEGIDO", "Tiempo consumido: %f ms\n", tiempoEntreSectores(posicionActualCabezal, sectorPedido1));
							imprimirProximoSectorLogueo();
							free(sectores);
							free(sectoresRecorridos);

							break;
						case 3:
							sectorPedido1 = ppd_LBAToCHS(colaLogueo[0]);
							sectorPedido2 = ppd_LBAToCHS(colaLogueo[1]);
							sectorPedido3 = ppd_LBAToCHS(colaLogueo[2]);
							log_info(logger, "PROCESO PEDIDO ELEGIDO", "Cola de Pedidos: [ %i:%i, %i:%i, %i:%i ] Tamaño: %i\n", sectorPedido1.cylinder, sectorPedido1.sector, sectorPedido2.cylinder, sectorPedido2.sector, sectorPedido3.cylinder, sectorPedido3.sector, sizeCola+sizeColaActiva);
							log_info(logger, "PROCESO PEDIDO ELEGIDO", "Posicion Actual: %i:%i\n", posicionActualCabezal.cylinder, posicionActualCabezal.sector);
							sectorPedido1 = ppd_LBAToCHS(pedidoPorProcesar.direccionSector);
							log_info(logger, "PROCESO PEDIDO ELEGIDO", "Sector Solicitado: %i:%i\n", sectorPedido1.cylinder, sectorPedido1.sector);
							sectores = SectoresRecorro(posicionActualCabezal, sectorPedido1);
							sectoresRecorridos = armarSectoresRecorridosLogueo(sectores, diferenciaEntreSectores(posicionActualCabezal, sectorPedido1));
							log_info(logger, "PROCESO PEDIDO ELEGIDO", "Sectores Recorridos: %s\n", sectoresRecorridos);
							log_info(logger, "PROCESO PEDIDO ELEGIDO", "Tiempo consumido: %f ms\n", tiempoEntreSectores(posicionActualCabezal, sectorPedido1));
							imprimirProximoSectorLogueo();
							free(sectores);
							free(sectoresRecorridos);
							break;
						case 4:
							sectorPedido1 = ppd_LBAToCHS(colaLogueo[0]);
							sectorPedido2 = ppd_LBAToCHS(colaLogueo[1]);
							sectorPedido3 = ppd_LBAToCHS(colaLogueo[2]);
							sectorPedido4 = ppd_LBAToCHS(colaLogueo[3]);
							log_info(logger, "PROCESO PEDIDO ELEGIDO", "Cola de Pedidos: [ %i:%i, %i:%i, %i:%i, %i:%i ] Tamaño: %i\n", sectorPedido1.cylinder, sectorPedido1.sector, sectorPedido2.cylinder, sectorPedido2.sector, sectorPedido3.cylinder, sectorPedido3.sector, sectorPedido4.cylinder, sectorPedido4.sector, sizeCola+sizeColaActiva);
							log_info(logger, "PROCESO PEDIDO ELEGIDO", "Posicion Actual: %i:%i\n", posicionActualCabezal.cylinder, posicionActualCabezal.sector);
							sectorPedido1 = ppd_LBAToCHS(pedidoPorProcesar.direccionSector);
							log_info(logger, "PROCESO PEDIDO ELEGIDO", "Sector Solicitado: %i:%i\n", sectorPedido1.cylinder, sectorPedido1.sector);
							sectores = SectoresRecorro(posicionActualCabezal, sectorPedido1);
							sectoresRecorridos = armarSectoresRecorridosLogueo(sectores, diferenciaEntreSectores(posicionActualCabezal, sectorPedido1));
							log_info(logger, "PROCESO PEDIDO ELEGIDO", "Sectores Recorridos: %s\n", sectoresRecorridos);
							log_info(logger, "PROCESO PEDIDO ELEGIDO", "Tiempo consumido: %f ms\n", tiempoEntreSectores(posicionActualCabezal, sectorPedido1));
							imprimirProximoSectorLogueo();
							free(sectores);
							free(sectoresRecorridos);
							break;
						case 5:
							sectorPedido1 = ppd_LBAToCHS(colaLogueo[0]);
							sectorPedido2 = ppd_LBAToCHS(colaLogueo[1]);
							sectorPedido3 = ppd_LBAToCHS(colaLogueo[2]);
							sectorPedido4 = ppd_LBAToCHS(colaLogueo[3]);
							sectorPedido5 = ppd_LBAToCHS(colaLogueo[4]);
							log_info(logger, "PROCESO PEDIDO ELEGIDO", "Cola de Pedidos: [ %i:%i, %i:%i, %i:%i, %i:%i, %i:%i ] Tamaño: %i\n", sectorPedido1.cylinder, sectorPedido1.sector, sectorPedido2.cylinder, sectorPedido2.sector, sectorPedido3.cylinder, sectorPedido3.sector, sectorPedido4.cylinder, sectorPedido4.sector,sectorPedido5.cylinder, sectorPedido5.sector, sizeCola+sizeColaActiva);
							log_info(logger, "PROCESO PEDIDO ELEGIDO", "Posicion Actual: %i:%i\n", posicionActualCabezal.cylinder, posicionActualCabezal.sector);
							sectorPedido1 = ppd_LBAToCHS(pedidoPorProcesar.direccionSector);
							log_info(logger, "PROCESO PEDIDO ELEGIDO", "Sector Solicitado: %i:%i\n", sectorPedido1.cylinder, sectorPedido1.sector);
							sectores = SectoresRecorro(posicionActualCabezal, sectorPedido1);
							sectoresRecorridos = armarSectoresRecorridosLogueo(sectores, diferenciaEntreSectores(posicionActualCabezal, sectorPedido1));
							log_info(logger, "PROCESO PEDIDO ELEGIDO", "Sectores Recorridos: %s\n", sectoresRecorridos);
							log_info(logger, "PROCESO PEDIDO ELEGIDO", "Tiempo consumido: %f ms\n", tiempoEntreSectores(posicionActualCabezal, sectorPedido1));
							imprimirProximoSectorLogueo();
							free(sectores);
							free(sectoresRecorridos);
							break;
						case 6:
							sectorPedido1 = ppd_LBAToCHS(colaLogueo[0]);
							sectorPedido2 = ppd_LBAToCHS(colaLogueo[1]);
							sectorPedido3 = ppd_LBAToCHS(colaLogueo[2]);
							sectorPedido4 = ppd_LBAToCHS(colaLogueo[3]);
							sectorPedido5 = ppd_LBAToCHS(colaLogueo[4]);
							sectorPedido6 = ppd_LBAToCHS(colaLogueo[5]);
							log_info(logger, "PROCESO PEDIDO ELEGIDO", "Cola de Pedidos: [ %i:%i, %i:%i, %i:%i, %i:%i, %i:%i, %i:%i ] Tamaño: %i\n", sectorPedido1.cylinder, sectorPedido1.sector, sectorPedido2.cylinder, sectorPedido2.sector, sectorPedido3.cylinder, sectorPedido3.sector, sectorPedido4.cylinder, sectorPedido4.sector,sectorPedido5.cylinder, sectorPedido5.sector, sectorPedido6.cylinder, sectorPedido6.sector, sizeCola+sizeColaActiva);
							log_info(logger, "PROCESO PEDIDO ELEGIDO", "Posicion Actual: %i:%i\n", posicionActualCabezal.cylinder, posicionActualCabezal.sector);
							sectorPedido1 = ppd_LBAToCHS(pedidoPorProcesar.direccionSector);
							log_info(logger, "PROCESO PEDIDO ELEGIDO", "Sector Solicitado: %i:%i\n", sectorPedido1.cylinder, sectorPedido1.sector);
							sectores = SectoresRecorro(posicionActualCabezal, sectorPedido1);
							sectoresRecorridos = armarSectoresRecorridosLogueo(sectores, diferenciaEntreSectores(posicionActualCabezal, sectorPedido1));
							log_info(logger, "PROCESO PEDIDO ELEGIDO", "Sectores Recorridos: %s\n", sectoresRecorridos);
							log_info(logger, "PROCESO PEDIDO ELEGIDO", "Tiempo consumido: %f ms\n", tiempoEntreSectores(posicionActualCabezal, sectorPedido1));
							imprimirProximoSectorLogueo();
							free(sectores);
							free(sectoresRecorridos);
							break;
						default :
							sectorPedido1 = ppd_LBAToCHS(colaLogueo[0]);
							sectorPedido2 = ppd_LBAToCHS(colaLogueo[1]);
							sectorPedido3 = ppd_LBAToCHS(colaLogueo[2]);
							sectorPedido4 = ppd_LBAToCHS(colaLogueo[3]);
							sectorPedido5 = ppd_LBAToCHS(colaLogueo[4]);
							sectorPedido6 = ppd_LBAToCHS(colaLogueo[5]);
							log_info(logger, "PROCESO PEDIDO ELEGIDO", "Cola de Pedidos: [ %i:%i, %i:%i, %i:%i ...  %i:%i, %i:%i, %i:%i ] Tamaño: %i\n", sectorPedido1.cylinder, sectorPedido1.sector, sectorPedido2.cylinder, sectorPedido2.sector, sectorPedido3.cylinder, sectorPedido3.sector, sectorPedido4.cylinder, sectorPedido4.sector,sectorPedido5.cylinder, sectorPedido5.sector, sectorPedido6.cylinder, sectorPedido6.sector, sizeCola+sizeColaActiva);
							log_info(logger, "PROCESO PEDIDO ELEGIDO", "Posicion Actual: %i:%i\n", posicionActualCabezal.cylinder, posicionActualCabezal.sector);
							sectorPedido1 = ppd_LBAToCHS(pedidoPorProcesar.direccionSector);
							log_info(logger, "PROCESO PEDIDO ELEGIDO", "Sector Solicitado: %i:%i\n", sectorPedido1.cylinder, sectorPedido1.sector);
							sectores = SectoresRecorro(posicionActualCabezal, sectorPedido1);
							sectoresRecorridos = armarSectoresRecorridosLogueo(sectores, diferenciaEntreSectores(posicionActualCabezal, sectorPedido1));
							log_info(logger, "PROCESO PEDIDO ELEGIDO", "Sectores Recorridos: %s\n", sectoresRecorridos);
							log_info(logger, "PROCESO PEDIDO ELEGIDO", "Tiempo consumido: %f ms\n", tiempoEntreSectores(posicionActualCabezal, sectorPedido1));
							imprimirProximoSectorLogueo();
							free(sectores);
							free(sectoresRecorridos);
							break;
					}*/

}

char *armarSectoresRecorridosLogueo(int32_t *ptrSectoresRecorridos, int32_t cantidadSectores)
{
	int32_t i=0;
	PPD_CHS aux;
	char auxchar[4];
	int32_t tamanioArray=0;
	int32_t caracteresEscritos;
	char *cilindro = malloc(sizeof(char)*4);
	char *sector = malloc(sizeof(char)*4);

	if(cantidadSectores < 20)
	{
		for( i=0; i<cantidadSectores; i++)
		{
			aux=ppd_LBAToCHS(ptrSectoresRecorridos[i]);
			caracteresEscritos=sprintf(auxchar,"%d",aux.cylinder);
			tamanioArray=tamanioArray+caracteresEscritos;
			tamanioArray=tamanioArray+strlen(":");
			caracteresEscritos=sprintf(auxchar,"%d",aux.sector);
			tamanioArray=tamanioArray+caracteresEscritos;
			tamanioArray=tamanioArray+strlen(" ");
		}
	}
	else
	{
		for( i=0; i<20; i++)
		{
			aux=ppd_LBAToCHS(ptrSectoresRecorridos[i]);
			caracteresEscritos=sprintf(auxchar,"%d",aux.cylinder);
			tamanioArray=tamanioArray+caracteresEscritos;
			tamanioArray=tamanioArray+strlen(":");
			caracteresEscritos=sprintf(auxchar,"%d",aux.sector);
			tamanioArray=tamanioArray+caracteresEscritos;
			tamanioArray=tamanioArray+strlen(" ")+strlen("... ");
		}
	}

	char *sectoresRecorridos = (char*)malloc(tamanioArray+5);

	//LIMPIO LA MEMORIA
	for (i= 0 ; i< tamanioArray; i++)
	{
		sectoresRecorridos[i]='\0';
	}

	//PREGUNTO SI LA CANTIDAD ES MENOR O IGUAL A 20, RECORRO DIRECTO, SINO RECORRO LOS PRIMEROS 10 Y LOS ULTIMOS 10
	if(cantidadSectores<=20)
	{
		if (cantidadSectores == 0)
		{
			strcpy(sectoresRecorridos, "...");
			return sectoresRecorridos;
		}

		for (i = 0; i<cantidadSectores;i++)
		{
			PPD_CHS sectorCargo;
			sectorCargo = ppd_LBAToCHS(ptrSectoresRecorridos[i]);
			sprintf(cilindro, "%d", sectorCargo.cylinder);
			sprintf(sector, "%d", sectorCargo.sector);
			strcat(sectoresRecorridos, cilindro);
			strcat(sectoresRecorridos, ":");
			strcat(sectoresRecorridos, sector);
			strcat(sectoresRecorridos, " ");
		}
	}
	else
	{
		for (i = 0; i<10;i++)
		{
			PPD_CHS sectorCargo;
			sectorCargo = ppd_LBAToCHS(ptrSectoresRecorridos[i]);
			sprintf(cilindro, "%d", sectorCargo.cylinder);
			sprintf(sector, "%d", sectorCargo.sector);
			strcat(sectoresRecorridos, cilindro);
			strcat(sectoresRecorridos, ":");
			strcat(sectoresRecorridos, sector);
			strcat(sectoresRecorridos, " ");
		}

		strcat(sectoresRecorridos, "... ");

		for(i = cantidadSectores-10; i < cantidadSectores; i++)
		{
			PPD_CHS sectorCargo;
			sectorCargo = ppd_LBAToCHS(ptrSectoresRecorridos[i]);
			sprintf(cilindro, "%d", sectorCargo.cylinder);
			sprintf(sector, "%d", sectorCargo.sector);
			strcat(sectoresRecorridos, cilindro);
			strcat(sectoresRecorridos, ":");
			strcat(sectoresRecorridos, sector);
			strcat(sectoresRecorridos, " ");
		}
	}

	free(sector);
	free(cilindro);
	return sectoresRecorridos;
}

void imprimirProximoSectorLogueo()
{
	int32_t next = ppd_CHStoLBA(proximoSectorPlanifico);

	switch(next)
	{
	case -1 :
		if (configuracion.LogActivado==1){
			log_info(logger, "PROCESO PEDIDO ELEGIDO", "Proximo sector: ... \n");
		}
		break;

	default :
		if (configuracion.LogActivado==1){
			log_info(logger, "PROCESO PEDIDO ELEGIDO", "Proximo sector: %i:%i \n", proximoSectorPlanifico.cylinder, proximoSectorPlanifico.sector);
		}
		break;
	}
}

